package com.parleys.android.client.service;

import org.apache.http.client.HttpClient;

import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;

import com.parleys.android.client.io.ChannelsHandler;
import com.parleys.android.client.io.NewsHandler;
import com.parleys.android.client.io.PresentationsHandler;
import com.parleys.android.client.io.RemoteExecutor;
import com.parleys.android.client.io.SpacesHandler;
import com.parleys.android.client.util.IOUtils;
import com.parleys.android.client.util.ParleysUriUtils;

public class ParleysService extends IntentService {

	private static final String TAG = "ParleysService";
	
    public static final String EXTRA_STATUS_RECEIVER 	= "com.parleys.android.client.extra.STATUS_RECEIVER";
    public static final String EXTRA_REST_OPERATION 	= "com.parleys.android.client.extra.REST_OPERATION";
    public static final String EXTRA_SPACE_ID		 	= "com.parleys.android.client.extra.SPACE_ID";
    public static final String EXTRA_CHANNEL_ID		 	= "com.parleys.android.client.extra.CHANNEL_ID";
    
    public static final String GENERAL_NEWS_REST_OPERATION		= "general_news";
    public static final String SPACES_REST_OPERATION			= "spaces";
    public static final String CHANNELS_REST_OPERATION			= "channels";
    public static final String PRESENTATIONS_REST_OPERATION		= "presentations";

    public static final int STATUS_RUNNING 		= 0x1;
    public static final int STATUS_ERROR 		= 0x2;
    public static final int STATUS_FINISHED		= 0x3;

    private HttpClient mHttpClient;
    private ContentResolver mResolver;
    private RemoteExecutor mExecutor;
    private SharedPreferences parleysServicePrefs;

    @Override
	public void onCreate() {
		super.onCreate();

		this.mHttpClient = IOUtils.getHttpClient(this);
		this.mResolver = getContentResolver();
		this.mExecutor = new RemoteExecutor(this.mHttpClient, this.mResolver);
        this.parleysServicePrefs = getSharedPreferences(ParleysServicePrefs.PARLEYS_SERVICE_PREFS, Context.MODE_PRIVATE);
	}

	public ParleysService() {
		super(TAG);
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		Log.d(TAG, "onHandleIntent()");
		
        final String restOperation = intent.getStringExtra(EXTRA_REST_OPERATION);
        if (GENERAL_NEWS_REST_OPERATION.equals(restOperation)) {
        	getGeneralNews(intent);
        } else if (SPACES_REST_OPERATION.equals(restOperation)) {
        	getSpaces(intent);
        } else if (CHANNELS_REST_OPERATION.equals(restOperation)) {
        	getChannels(intent);
        } else if (PRESENTATIONS_REST_OPERATION.equals(restOperation)) {
        	getPresentations(intent);
        }
	}
	
	private void getGeneralNews(Intent intent) {
        final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER);
        if (receiver != null) receiver.send(STATUS_RUNNING, Bundle.EMPTY);

        try {
        	final long startSync = System.currentTimeMillis();
        	final long lastSync = parleysServicePrefs.getLong(ParleysServicePrefs.LAST_SYNC_GENERAL_NEWS, 0);
			mExecutor.executeGet(ParleysUriUtils.buildProxyNewsUri(lastSync), new NewsHandler());
			parleysServicePrefs.edit().putLong(ParleysServicePrefs.LAST_SYNC_GENERAL_NEWS, startSync).commit();
		} catch (Exception e) {
			Log.e(TAG, "Problem while syncing", e);

            if (receiver != null) {
                final Bundle bundle = new Bundle();
                bundle.putString(Intent.EXTRA_TEXT, e.toString());
                receiver.send(STATUS_ERROR, bundle);
            }
		}

		if (receiver != null) receiver.send(STATUS_FINISHED, Bundle.EMPTY);
	}
	
	private void getSpaces(Intent intent) {
        final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER);
        if (receiver != null) receiver.send(STATUS_RUNNING, Bundle.EMPTY);

        try {
			mExecutor.executeGet(ParleysUriUtils.buildProxySpacesUri(), new SpacesHandler());
		} catch (Exception e) {
			Log.e(TAG, "Problem while syncing", e);

            if (receiver != null) {
                final Bundle bundle = new Bundle();
                bundle.putString(Intent.EXTRA_TEXT, e.toString());
                receiver.send(STATUS_ERROR, bundle);
            }
		}

		if (receiver != null) receiver.send(STATUS_FINISHED, Bundle.EMPTY);
	}
	
	private void getChannels(Intent intent) {
        final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER);
		final int spaceId = intent.getIntExtra(EXTRA_SPACE_ID, -1);
		if (spaceId != -1) {
	        if (receiver != null) receiver.send(STATUS_RUNNING, Bundle.EMPTY);
	
	        try {
				mExecutor.executeGet(ParleysUriUtils.buildProxyChannelsUri(spaceId), new ChannelsHandler());
			} catch (Exception e) {
				Log.e(TAG, "Problem while syncing", e);
	
	            if (receiver != null) {
	                final Bundle bundle = new Bundle();
	                bundle.putString(Intent.EXTRA_TEXT, e.toString());
	                receiver.send(STATUS_ERROR, bundle);
	            }
			}
	
			if (receiver != null) receiver.send(STATUS_FINISHED, Bundle.EMPTY);
		} else {
            if (receiver != null) {
	            final Bundle bundle = new Bundle();
	            bundle.putString(Intent.EXTRA_TEXT, "Invalid space identifier '" + spaceId + "'");
	            receiver.send(STATUS_ERROR, bundle);
            }
		}
	}
	
	private void getPresentations(Intent intent) {
        final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER);
		final int channelId = intent.getIntExtra(EXTRA_CHANNEL_ID, -1);
		if (channelId != -1) {
	        if (receiver != null) receiver.send(STATUS_RUNNING, Bundle.EMPTY);
	
	        try {
				mExecutor.executeGet(ParleysUriUtils.buildProxyPresentationsUri(channelId), new PresentationsHandler());
			} catch (Exception e) {
				Log.e(TAG, "Problem while syncing", e);
	
	            if (receiver != null) {
	                final Bundle bundle = new Bundle();
	                bundle.putString(Intent.EXTRA_TEXT, e.toString());
	                receiver.send(STATUS_ERROR, bundle);
	            }
			}
	
			if (receiver != null) receiver.send(STATUS_FINISHED, Bundle.EMPTY);
		} else {
            if (receiver != null) {
	            final Bundle bundle = new Bundle();
	            bundle.putString(Intent.EXTRA_TEXT, "Invalid channel identifier '" + channelId + "'");
	            receiver.send(STATUS_ERROR, bundle);
            }
		}
	}
	
	private interface ParleysServicePrefs {
		String PARLEYS_SERVICE_PREFS 		= "parleys_service_prefs";
		String LAST_SYNC_GENERAL_NEWS		= "last_sync_general_news";
	}

}
